package stream;

import org.junit.Test;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @Auther lujieni
 * @Date 2020/6/23
 * 测试使用stream的group by进行分组
 * 这里特别要注意,分组后对数据的修改是对象传递,原本的list也会受到影响!!!
 */
public class UseGroupBy {

    public  <T, A> Collector<T, ?, Map<A, List<T>>> groupByWithNullKeys(Function<? super T, ? extends A> classifier) {
        return Collectors.toMap(
                classifier,
                Collections::singletonList,
                (List<T> oldList, List<T> newEl) -> {
                    List<T> newList = new ArrayList<>(oldList.size() + 1);
                    newList.addAll(oldList);
                    newList.addAll(newEl);
                    return newList;
                }
        );
    }

    @Test
    public void test3(){
        Stream <String> stream = Stream.of("I", "love", "you", "too");
        List<Integer> result = stream.map(e -> e.length()).collect(Collectors.toList());
        System.out.println(result);
    }

    @Test
    public void test2(){
        Student s1 = new Student(22,"张三");
        Student s2 = new Student(22,"李四");
        Student s3 = new Student(8,"阿虎");
        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        Map<Integer, List<Student>> resultMap = list.stream().collect(Collectors.groupingBy(e -> e.getAge()));
        for(Map.Entry<Integer, List<Student>> entry : resultMap.entrySet()){
            Integer key = entry.getKey();
            List<Student> value = entry.getValue();
            System.out.println(key+":"+value);
        }
    }

    @Test
    public void test(){
        Student s1 = new Student(22,"张三");
        Student s2 = new Student(22,"李四");
        Student s3 = new Student(8,"阿虎");
        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);

        Map<Integer, List<Student>> map = list.stream().collect(Collectors.groupingBy(e -> e.getAge()));

        for (Map.Entry<Integer, List<Student>> entry: map.entrySet()) {
            List<Student> value = entry.getValue();
            for (Student s: value) {
                if(Objects.equals(s.getAge(),22)){
                    s.setSchool("大学");
                }
                if(Objects.equals(s.getAge(),8)){
                    s.setSchool("小学");
                }
            }
        }
        System.out.println(map);
        System.out.println(list); //list和map中的元素是同一组对象
    }

    @Test
    public void test4(){
        Student s1 = new Student(22,"张三");
        Student s2 = new Student(22,"李四");
        Student s3 = new Student(8,"阿虎");
        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);

        Map<Integer, List<Student>> map = new HashMap<>();
        list.forEach(e->{
            map.computeIfAbsent(e.getAge(), k -> new ArrayList<>()).add(e);
        });
        System.out.println(map);
    }

    public static void test5(){
        Student s1 = new Student(22,"张三");
        Student s2 = new Student(22,"李四");
        Student s3 = new Student(8,"阿虎");
        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        Map<Integer, List<Student>> collect = list.stream().collect(Collectors.groupingBy(Student::getAge));
        System.out.println(collect);
    }

    @Test
    public void test6(){
        List<String> list = Arrays.asList("a", "b", "a");
        List<String> collect = IntStream.range(0, list.size()).boxed().collect(Collectors.groupingBy(e -> list.get(e))).values().stream().filter(e -> e.size() > 1).flatMap(e -> e.stream().map(item -> "第" + (item + 1) + "行")).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(collect)){
            System.out.println(String.join(",", collect)+"重复");
        }

    }

    @Test
    public void test7(){
        Student s1 = new Student(22,"张三");
        Student s2 = new Student(22,"张三");
        Student s3 = new Student(22,"齐齐");
        Student s4 = new Student(8,"阿虎");
        List<Student> list = new ArrayList<>();
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        Map<String, List<Student>> collect = list.stream().collect(Collectors.groupingBy(e -> e.getName() + ":" + e.getAge()));
        List<Student> students = collect.get("张三:22");
        System.out.println(students);
    }


}
